#include "i_processes.h"
#include "processes.h"
#include "messages.h"
#include "kernel.h"
#include "globals.h"
#include "context.h"
#include "proctables.h"
#include "processes.h"
#include "debug.h"

VOID setIProcInfo() {
	RTX_PROCS[UART_I_PROCESS].pid = UART_I_PROCESS;
	RTX_PROCS[UART_I_PROCESS].priority = 0x0;
	RTX_PROCS[UART_I_PROCESS].stacksize = 4096;
	RTX_PROCS[UART_I_PROCESS].rtx_proc_entry = uart_i_process;

	RTX_PROCS[TIMER_I_PROCESS].pid = TIMER_I_PROCESS;
	RTX_PROCS[TIMER_I_PROCESS].priority = 0x0;
	RTX_PROCS[TIMER_I_PROCESS].stacksize = 4096;
	RTX_PROCS[TIMER_I_PROCESS].rtx_proc_entry = timer_i_process;
}

MESSAGE* peek_message() {
	return current_process->message_queue_head;
}

VOID uart_i_process() {
	UINT32* msg = NULL;
	BYTE temp = NULL;
	BYTE charVal = NULL;

	while(TRUE)
	{
		temp = SERIAL1_UCSR;

		/* See if data is waiting */
		if (temp & 1)
		{
			charVal = SERIAL1_RD;
			msg = kernel_request_memory_block();
			if(msg != NULL) {
				*(msg + 64) = charVal;

				if(screen_ready) {
					SERIAL1_WD = charVal;
					screen_ready = FALSE;
					SERIAL1_IMR = 3;
				} else {
					UINT32* msg2 = kernel_request_memory_block();

					if(msg2 != NULL) {
						kernel_send_message(UART_I_PROCESS, msg2);
					}
				}

				kernel_send_message(KCD_PROCESS, msg);
			}
		}
		/* See if port is ready to accept data */
		else if (temp & 4 || screen_ready)
		{
			UINT32 sender = 0;
			msg = kernel_receive_message(&sender);

			if(msg != NULL) {
				charVal = *(msg + 64);

				SERIAL1_WD = charVal;

				kernel_release_memory_block(msg);

				screen_ready = FALSE;
				SERIAL1_IMR = 3;
			} else if(!screen_ready) {
				screen_ready = TRUE;
				SERIAL1_IMR = 2;
			}
		}

		i_process_switch();
	}
}

VOID timer_i_process() {
	MESSAGE* msg = NULL;
	UINT32 sender;

	while(TRUE)
	{
		current_time += 1;

		while(msg = peek_message()) {
			if(msg->number_of_clock_ticks > current_time) {
				break;
			}
			msg = kernel_receive_message(&sender);
			kernel_send_message(NULL, msg);
		}

		TIMER0_TER = 2;

		i_process_switch();
	}
}
